﻿using SqlSugar;

namespace DoNet.ORM.Repository.Repository
{
    /// <summary>
    /// ‌
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SqlSugarRepository : IRepository
    {
        /// <summary>
        /// 
        /// </summary>
        private SqlSugarClient _db;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        /// <param name="connectionString"></param>
        public SqlSugarRepository(DataBaseType dbType, string connectionString)
        {
            _db = new SqlSugarClient(new ConnectionConfig
            {
                ConnectionString = connectionString,
                DbType = GetDbType(dbType),
                IsAutoCloseConnection = true
            });
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataBaseType"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public DbType GetDbType(DataBaseType dataBaseType)
        {
            return dataBaseType switch
            {
                DataBaseType.MySql => DbType.MySql,
                DataBaseType.SqlServer => DbType.SqlServer,
                DataBaseType.Sqlite => DbType.Sqlite,
                DataBaseType.Oracle => DbType.Oracle,
                DataBaseType.PostgreSQL => DbType.PostgreSQL,
                DataBaseType.Dm => DbType.Dm,
                DataBaseType.Kdbndp => DbType.Kdbndp,
                DataBaseType.DB2 => DbType.DB2,
                _ => throw new ArgumentException("不支持的 数据库 类型")
            };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        public long Insert<T>(T entity) where T : class, new()
        {
            return _db.Insertable<T>(entity).ExecuteCommand();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<long> InsertAsync<T>(T entity) where T : class, new() => await _db.Insertable(entity).ExecuteCommandAsync();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public long Update<T>(T entity) where T : class, new() => _db.Updateable(entity).ExecuteCommand();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<long> UpdateAsync<T>(T entity) where T : class, new() => await _db.Updateable(entity).ExecuteCommandAsync();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public long Delete<T>(T entity) where T : class, new() => _db.Deleteable(entity).ExecuteCommand();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<long> DeleteAsync<T>(T entity) where T : class, new() => await _db.Deleteable(entity).ExecuteCommandAsync();
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IEnumerable<T> GetAll<T>() where T : class, new() => _db.Queryable<T>().ToList();
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<T>> GetAllAsync<T>() where T : class, new() => await _db.Queryable<T>().ToListAsync();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetById<T>(long id) where T : class, new() => _db.Queryable<T>().InSingle(id);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<T?> GetByIdAsync<T>(long id) where T : class, new() => await _db.Queryable<T>().InSingleAsync(id);

        #region 事务
        /// <summary>
        /// 同步开启事务
        /// </summary>
        public void BeginTransaction()
        {
            _db.Ado.BeginTran();
        }
        /// <summary>
        /// 同步提交事务
        /// </summary>
        public void CommitTransaction()
        {
            _db.Ado.CommitTran();
        }
        /// <summary>
        /// 同步回滚事务
        /// </summary>
        public void RollbackTransaction()
        {
            _db.Ado.RollbackTran();
        }
        /// <summary>
        /// 异步开启事务
        /// </summary>
        public async Task BeginTransactionAsync()
        {
            await _db.Ado.BeginTranAsync();
        }
        /// <summary>
        /// 异步提交事务
        /// </summary>
        public async Task CommitTransactionAsync()
        {
            await _db.Ado.CommitTranAsync();
        }
        /// <summary>
        /// 异步回滚事务
        /// </summary>
        public async Task RollbackTransactionAsync()
        {
            await _db.Ado.RollbackTranAsync();
        }
        #endregion 事务
    }
}
